/*
 * Project: Sudoku Hint Engine for Android
 * Copyright (C) 2010-2013 Emanuel Moecklin
 * 
 * Available under the terms of the Lesser General Public License (LGPL)
 */
package com.onegravity.sudoku.solver.core;

import com.onegravity.sudoku.solver.HintEngine;
import com.onegravity.sudoku.solver.R;

/*
	VERY_EASY
		1.0: Full House in block, row or column
		1.2: Hidden Single in block
		
	EASY
		1.3: Full House in extra region
		1.5: Hidden Single in row or column
		
	MODERATE
		1.8: Hidden Single in extra region
		2.3: Naked Single
		
	ADVANCED
		2.6: Pointing
		2.8: Pointing with extra regions
		2.8: Claiming
		
	HARD
		3.0: Claiming with extra regions
		3.0: Naked Pair
		3.2: Naked Pair in extra region
		3.2: X-Wing
		3.4: Hidden Pair
		3.4: Finned X-Wing
		3.5: Sashimi X-Wing
		
	VERY_HARD
		3.6: Hidden Pair in extra region
		3.6: Naked Triple
		3.8: Naked Triple in extra region
		3.8: Swordfish
		4.0: Hidden Triple
		4.0: Finned Swordfish
		4.2: Sashimi Swordfish
		4.2: Hidden Triple in extra region
		4.2-4.4: XY-Wing (+0.2 for jigsaw or extra region)
		4.4: XYZ-Wing
		4.4: W-Wing
		 
	FIENDISH
		4.5 Almost Locked Candidates (Pair)
		4.5: Avoidable Rectangle Type 2
		4.6: XY-Wing jigsaw puzzle and extra region
		4.7: Avoidable Rectangle Type 1
		4.5-5.0: Unique rectangles and loops
		4.6-4.8: XYZ-Wing jigsaw puzzle or extra region (+0.2 for both)
		4.8: Hidden Unique Rectangle
		4.6-5.0: WXYZ-Wing (+0.2 for jigsaw or extra region, +0.4 for both)
		4.8-5.2: VWXYZ-Wing (+0.2 for jigsaw or extra region, +0.4 for both)
		5.0: Sue de Coq
		5.0: Remote Pairs
		5.0: Naked Quad
		5.0-5.4: UVWXYZ-Wing (+0.2 for jigsaw or extra region, +0.4 for both)
		5.2: Naked Quad in extra region
		5.2: Jellyfish
		5.2-5.6: TUVWXYZ-Wing (+0.2 for jigsaw or extra region, +0.4 for both)
		5.2 Almost Locked Candidates (Triple)
		5.4: Hidden Quad
		5.4: Finned Jellyfish
		5.4-5.8: STUVWXYZ-Wing (+0.2 for jigsaw or extra region, +0.4 for both)
		5.6: Sashimi Jellyfish
		5.6: Hidden Quad in extra region
		5.6-6.0: RSTUVWXYZ-Wing (+0.2 for jigsaw or extra region, +0.4 for both)
		5.6: BUG+1
		5.7: BUG+2
		5.8 - 6.0: BUG+3
		5.7: BUG+4
		5.8 Almost Locked Candidates (Quad)
		6.2: Aligned Pair Exclusion
		
	NIGHTMARE
		6.4: Aligned Pair Exclusion jigsaw puzzle
		6.4: Aligned Pair Exclusion with extra region
		6.6: Aligned Pair Exclusion jigsaw puzzle with extra regions
		6.5 - 7.5: Bidirectioal X-Cycles and Y-Cycles
		6.6 - 7.6: Forcing X-Chains, Forcing XY-Chains
		7.0 - 8.0: Forcing Chains, Bidirectional Cycles
		7.5: ALS-XZ
		8.0: ALS-XY-Wing
		7.5: Aligned Triple Exclusion
		7.7: Aligned Triple Exclusion jigsaw puzzle
		7.7: Aligned Triple Exclusion with extra regions
		7.9: Aligned Triple Exclusion jigsaw puzzle with extra regions
		7.5 - 8.5: Nishio
		8.0 - 9.0: Cell/Region Forcing Chains
		8.5 - 9.5: Dynamic Forcing Chains
		9.0 - 10.0: Dynamic Forcing Chains (+)
		> 9.5: Nested Forcing Chains
		
	BEYOND_NIGHTMARE
		> 10.0: Nested Forcing Chains
*/

public enum Difficulty {
	UNKNOWN(0.0, 0.0, R.string.sudoku_difficulty_unknown, 0),
	VERY_EASY(0.99, 1.25, R.string.sudoku_difficulty_veryeasy, 1),
	EASY(1.26, 1.55, R.string.sudoku_difficulty_easy, 2),			
	MODERATE(1.56, 2.35, R.string.sudoku_difficulty_moderate, 3),	
	ADVANCED(2.36, 2.85, R.string.sudoku_difficulty_advanced, 4),	
	HARD(2.86, 3.55, R.string.sudoku_difficulty_hard, 5),			
	VERY_HARD(3.56, 4.45, R.string.sudoku_difficulty_veryhard, 6),	
	FIENDISH(4.46, 6.25, R.string.sudoku_difficulty_fiendish, 7),	
	NIGHTMARE(6.26, 10.05, R.string.sudoku_difficulty_nightmare, 8),
	BEYOND_NIGHTMARE(10.06, 99.9, R.string.sudoku_difficulty_beyond_nightmare, 9);
	
	private double minDifficulty;
	private double maxDifficulty;
	private int resID;
	private String name;
	private int key;
	
	private Difficulty(double minDifficulty, double maxDifficulty, int resID, int key) {
		this.minDifficulty = minDifficulty;
		this.maxDifficulty = maxDifficulty;
		this.resID = resID;
		this.key = key;
	}
	
	public double getMinDifficulty() {
		return minDifficulty;
	}

	public double getMaxDifficulty() {
		return maxDifficulty;
	}

	public String getName() {
		if (name==null) name = HintEngine.getContext().getString(resID); 
		return name;
	}

	public int key() {
		return key;
	}
	
	public int resID() {
		return resID;
	}
	
	public static final Difficulty newInstance(int key) {
		switch(key) {
		case 1: return VERY_EASY;
		case 2: return EASY;
		case 3: return MODERATE;
		case 4: return ADVANCED;
		case 5: return HARD;
		case 6: return VERY_HARD;
		case 7: return FIENDISH;
		case 8: return NIGHTMARE;
		case 9: return BEYOND_NIGHTMARE;
		default: return UNKNOWN;
		}
	}

	public static final Difficulty newInstance(double rating) {
		return (rating>=VERY_EASY.minDifficulty && rating<=VERY_EASY.maxDifficulty) ? VERY_EASY :
			   (rating>=EASY.minDifficulty && rating<=EASY.maxDifficulty) ? EASY :
			   (rating>=MODERATE.minDifficulty && rating<=MODERATE.maxDifficulty) ? MODERATE :
			   (rating>=ADVANCED.minDifficulty && rating<=ADVANCED.maxDifficulty) ? ADVANCED :
			   (rating>=HARD.minDifficulty && rating<=HARD.maxDifficulty) ? HARD :
			   (rating>=VERY_HARD.minDifficulty && rating<=VERY_HARD.maxDifficulty) ? VERY_HARD :
			   (rating>=FIENDISH.minDifficulty && rating<=FIENDISH.maxDifficulty) ? FIENDISH :
			   (rating>=NIGHTMARE.minDifficulty && rating<=NIGHTMARE.maxDifficulty) ? NIGHTMARE :
			   (rating>=BEYOND_NIGHTMARE.minDifficulty) ? BEYOND_NIGHTMARE :
			   UNKNOWN;
	}
}
